package com.mar.framecompress;

/**
 * TODO: introduce Pixel Format Builder.
 * @author mar
 */
public class PixelFormat {

	public final int bpp;
	public final int depth;
	public final boolean bigEndian;
	public final boolean trueColour;
	public final int redMax;
	public final int greenMax;
	public final int blueMax;
	public final int redShift;
	public final int greenShift;
	public final int blueShift;

	public PixelFormat(int b, int d, boolean e, boolean t) {
		this(b, d, e, t, 7, 7, 3, 0, 3, 6);
	}

	public PixelFormat(int b, int d, boolean e, boolean t, int rm, int gm,
			int bm, int rs, int gs, int bs) {
		bpp = b;
		depth = d;
		bigEndian = e;
		trueColour = t;

		redMax = rm;
		greenMax = gm;
		blueMax = bm;
		redShift = rs;
		greenShift = gs;
		blueShift = bs;
	}

	public PixelFormat() {
		this(8, 8, false, true, 7, 7, 3, 0, 3, 6);
	}

	@Override
	public boolean equals(Object obj) {
		if (obj instanceof PixelFormat) {
			return equal((PixelFormat) obj);
		}
		return false;
	}

	public boolean equal(PixelFormat x) {
		return (bpp == x.bpp && depth == x.depth
				&& (bigEndian == x.bigEndian || bpp == 8)
				&& trueColour == x.trueColour && (!trueColour || (redMax == x.redMax
				&& greenMax == x.greenMax
				&& blueMax == x.blueMax
				&& redShift == x.redShift && greenShift == x.greenShift && blueShift == x.blueShift)));
	}

	public String toString() {
		StringBuffer s = new StringBuffer();
		s.append("depth " + depth + " (" + bpp + "bpp)");
		if (bpp != 8) {
			if (bigEndian)
				s.append(" big-endian");
			else
				s.append(" little-endian");
		}

		if (!trueColour) {
			s.append(" colour-map");
			return s.toString();
		}

		if (blueShift == 0 && greenShift > blueShift && redShift > greenShift
				&& blueMax == (1 << greenShift) - 1
				&& greenMax == (1 << (redShift - greenShift)) - 1
				&& redMax == (1 << (depth - redShift)) - 1) {
			s.append(" rgb" + (depth - redShift) + (redShift - greenShift)
					+ greenShift);
			return s.toString();
		}

		if (redShift == 0 && greenShift > redShift && blueShift > greenShift
				&& redMax == (1 << greenShift) - 1
				&& greenMax == (1 << (blueShift - greenShift)) - 1
				&& blueMax == (1 << (depth - blueShift)) - 1) {
			s.append(" bgr" + (depth - blueShift) + (blueShift - greenShift)
					+ greenShift);
			return s.toString();
		}

		s.append(" rgb max " + redMax + "," + greenMax + "," + blueMax
				+ " shift " + redShift + "," + greenShift + "," + blueShift);
		return s.toString();
	}
}
